library libcue;

uses
  SysUtils,
  Classes,
  cue in 'cue.pas',
  WideStringList in 'WideStringList.pas',
  WideStrUtils in 'WideStrUtils.pas';

type
  TCUEEntryInfo = record
    Filename: PWideChar;
    Tracks: integer;
    EntryClass: integer;
  end;

  TCUETrackInfo = record
    Index: integer;
    Title,
    Performer,
    Songwriter: PWideChar;
    ISRC: shortString;
    Pregap,Postgap: TCUEMSF;
    TrackClass: integer;
    IndexCount: integer;
    Length: integer;
  end;

const
  CUE_INFO_TITLE = 0;
  CUE_INFO_PERFORMER = 1;
  CUE_INFO_SONGWRITER = 2;
  CUE_INFO_CATALOG = 3;
  CUE_INFO_CDTEXT = 4;
  CUE_INFO_DISCID = 5;
  CUE_INFO_GENRE = 6;
  CUE_INFO_DATE = 7;

{$R *.res}

function CUE_Init: Pointer; cdecl; export;
begin
  Result := TCUESheet.Create;
end;

procedure CUE_Release(var cs: Pointer); cdecl; export;
begin
  try
    TCUESheet(cs).Free;
    cs := nil;
  except end;
end;

function CUE_Load(cs: pointer; const CUEFile: PWideChar): boolean; cdecl; export;
begin
  Result := false;
  if not (TObject(cs) is TCUESheet) or not Assigned(cs) then exit;
  Result := CUEFile <> nil;
  if Result then TCUESheet(cs).Load(WideString(CUEFile));
end;

function CUE_GlobalInfo(cs: pointer; const Flag: integer; out Info: PWideChar): boolean; cdecl; export;
begin
  Result := false;
  if not (TObject(cs) is TCUESheet) or not Assigned(cs) then exit;
  case Flag of
    CUE_INFO_TITLE: Info := PWideChar(TCUESheet(cs).Title);
    CUE_INFO_PERFORMER: Info := PWideChar(TCUESheet(cs).Performer);
    CUE_INFO_SONGWRITER: Info := PWideChar(TCUESheet(cs).Songwriter);
    CUE_INFO_CATALOG: Info := PWideChar(TCUESheet(cs).Catalog);
    CUE_INFO_CDTEXT: Info := PWideChar(TCUESheet(cs).CDTextFile);
    CUE_INFO_DISCID: Info := PWideChar(widestring(TCUESheet(cs).DiscID));
    CUE_INFO_GENRE: Info := PWideChar(TCUESheet(cs).Genre);
    CUE_INFO_DATE: Info := PWideChar(TCUESheet(cs).Date);
  else
    exit;
  end;
  Result := Info <> nil;
end;

function CUE_EntryCount(cs: Pointer): integer; cdecl; export;
begin
  Result:= -1;
  if not (TObject(cs) is TCUESheet) or not Assigned(cs) then exit;
  Result := TCUESheet(cs).EntryCount;
end;

function CUE_GetEntry(cs: Pointer; const Index: integer): pointer; cdecl; export;
begin
  Result:= nil;
  if not (TObject(cs) is TCUESheet) or not Assigned(cs) then exit;
  Result := TCUESheet(cs).Entry[index];
end;

function CUE_GetEntryInfo(Entry: pointer; out Info: TCUEEntryInfo): boolean; cdecl; export;
begin
  Result := false;
  if not (TObject(Entry) is TCUEFileEntry) or not Assigned(Entry) then exit;
  Info.Filename := PWideChar(TCUEFileEntry(Entry).Filename);
  Info.Tracks := TCUEFileEntry(Entry).TrackCount;
  Info.EntryClass := Integer(TCUEFileEntry(Entry).EntryClass);
  Result := true;
end;

function CUE_GetEntryTrack(Entry: pointer; const Index: integer): pointer; cdecl; export;
begin
  Result := nil;
  if not (TObject(Entry) is TCUEFileEntry) or not Assigned(Entry) then exit;
  Result := TCUEFileEntry(Entry).Track[index];
end;

function CUE_GetTrackInfo(Track: pointer; out Info: TCUETrackInfo): boolean; cdecl; export;
begin
  Result := false;
  if not (TObject(Track) is TCUETrack) or not Assigned(Track) then exit;

  Info.Title := PWideChar(TCUETrack(Track).Title);
  Info.Performer := PWideChar(TCUETrack(Track).Performer);
  Info.Songwriter := PWideChar(TCUETrack(Track).Songwriter);
  Info.ISRC := TCUETrack(Track).ISRC;
  Info.Index := TCUETrack(Track).Index;

  Info.TrackClass := integer(TCUETrack(Track).TrackType);
  Info.Pregap := TCUETrack(Track).Pregap;
  Info.Postgap := TCUETrack(Track).Postgap;
  Info.IndexCount := TCUETrack(Track).TrackIndexCount;

  Info.Length := TCUETrack(Track).Length;

  Result := true;
end;

function CUE_GetTrackIndex(Track: pointer; const Index: integer; const Sequental: boolean; out Info: TCUETrackIndex): boolean; cdecl; export;
var idx: integer;
begin
  Result := false;
  if not (TObject(Track) is TCUETrack) or not Assigned(Track) then exit;

  if Sequental then begin
    if Index < TCUETrack(Track).TrackIndexCount then idx := Index else idx := -1;
  end else idx := TCUETrack(Track).FindIndex(index);

  if idx <> -1 then
    try
      Info := TCUETrack(Track).TrackIndex[idx];
      Result := true;
    except
    end;
end;

exports
  CUE_Init,
  CUE_Release,
  CUE_Load,
  CUE_GlobalInfo,

  CUE_EntryCount,
  CUE_GetEntry,
  CUE_GetEntryInfo,
  CUE_GetEntryTrack,

  CUE_GetTrackInfo,
  CUE_GetTrackIndex;
  
end.
 